import { Injectable } from '@nestjs/common';
import { ExCode_Create_Dto, ExCode_ExChange_Dto, ExCode_Update_Dto } from './assets/exCode.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { ExCode } from './assets/exCode.entity';
import { Repository } from 'typeorm';
import { ExCode_Find_Dto } from './assets/exCode.dto';
import { util_Db_Add, util_Db_Delete, util_Db_PageList, util_Db_Update } from '@/common/util/db';
import { Coupon } from '../coupon/assets/coupon.entity';
import * as base62 from 'base62/lib/ascii';
import { IRequest } from '@/common/typeScripts';
import { Constant_Enum_Enum_ExCode_ExCodeValue } from '@/common/constants/enum';
import { Class_HttpException_Base } from '@/common/classes/httpException';
import { CouponUserClient } from '../couponUserClient/assets/couponUserClient.entity';
import { CouponUserClient_Service } from '../couponUserClient/couponUserClient.service';

@Injectable()
export class ExCode_Service {
  constructor(
    @InjectRepository(CouponUserClient)
    private couponUserClient_Repository: Repository<CouponUserClient>,
    @InjectRepository(Coupon)
    private coupon_Repository: Repository<Coupon>,
    @InjectRepository(ExCode)
    private exCode_Repository: Repository<ExCode>,
    private couponUserClient_Service: CouponUserClient_Service,
  ) {}

  async exCode_Create(body: ExCode_Create_Dto) {
    const coupon = this.coupon_Repository.create({
      id: body.couponId,
    });
    const exCodeList = [];
    for (let index = 0; index < body.exCodeNum; index++) {
      exCodeList.push({
        exCodeValue: base62.encode(new Date().getTime() + index * 100),
        // exCodeStatus: body.exCodeStatus,
        coupon,
      });
    }
    return await util_Db_Add({
      createDto: exCodeList,
      repository: this.exCode_Repository,
    });
  }

  async exCode_FindByPage(query: ExCode_Find_Dto) {
    return await util_Db_PageList<ExCode>({
      queryBuilder: this.exCode_Repository
        .createQueryBuilder('exCode')
        .leftJoin('exCode.coupon', 'coupon')
        .select([
          'exCode.id AS id',
          'exCode.exCodeValue AS exCodeValue',
          'exCode.exCodeStatus AS exCodeStatus',
        ]),
      query,
      isRaw: true,
    });
  }

  async exCode_FindOneById(id: number) {
    return await this.exCode_Repository
      .createQueryBuilder('exCode')
      .andWhere(`exCode.id = :id`, { id: id })
      .getOne();
  }

  async exCode_Update(body: ExCode_Update_Dto) {
    return await util_Db_Update({
      findOne: () => this.exCode_FindOneById(body.id),
      updateDto: body,
      repository: this.exCode_Repository,
    });
  }

  async exCode_Remove(id: number) {
    return await util_Db_Delete({
      findOne: () => this.exCode_FindOneById(id),
      id,
      repository: this.exCode_Repository,
    });
  }

  async exCode_Web_Exchange(query: ExCode_ExChange_Dto, req: IRequest) {
    const coupon = await this.coupon_Repository
      .createQueryBuilder('coupon')
      .where('exCode=:exCode', { exCode: query.exCode })
      .getOne();
    if (coupon) {
      const couponUser = await this.coupon_Repository
        .createQueryBuilder('coupon')
        .leftJoinAndSelect('coupon.userClient', 'userClient')
        .where('coupon.id = :id', {
          id: coupon.id,
        })
        .andWhere('userClient.id = :userClientId', {
          userClientId: req.user.userId,
        })
        .getOne();
      if (couponUser) throw new Class_HttpException_Base('已拥有该优惠券');
      const couponUserClients = this.couponUserClient_Service.couponUserClient_Util_Create({
        userClient: req.user.userId,
        coupons: [coupon],
      });
      await util_Db_Add({
        createDto: couponUserClients,
        repository: this.couponUserClient_Repository,
      });
    } else {
      const excode = await this.exCode_Repository
        .createQueryBuilder('excode')
        .leftJoinAndSelect('excode.coupon', 'coupon')
        .where('exCodeValue=:exCodeValue', { exCodeValue: query.exCode })
        .getOne();
      if (excode.exCodeStatus == Constant_Enum_Enum_ExCode_ExCodeValue.ExCode_ExCodeValue_Used)
        throw new Class_HttpException_Base('该兑换码已被使用！');
      excode.exCodeStatus = Constant_Enum_Enum_ExCode_ExCodeValue.ExCode_ExCodeValue_Used;
      const couponUser = await this.coupon_Repository
        .createQueryBuilder('coupon')
        .leftJoinAndSelect('coupon.userClient', 'userClient')
        .where('coupon.id = :id', {
          id: excode.coupon.id,
        })
        .andWhere('userClient.id = :userClientId', {
          userClientId: req.user.userId,
        })
        .getOne();
      if (couponUser) throw new Class_HttpException_Base('已拥有该优惠券');
      this.exCode_Update(excode);
      const couponUserClients = this.couponUserClient_Service.couponUserClient_Util_Create({
        userClient: req.user.userId,
        coupons: [excode.coupon],
      });
      await util_Db_Add({
        createDto: couponUserClients,
        repository: this.couponUserClient_Repository,
      });
    }
    return '兑换成功';
  }
}
